﻿# -*- coding: utf-8

import sys

from collections import OrderedDict

import re

def convert_lookfor( s ):
	male = u'парнем'
	female = u'девушкой'	

	if male in s and female in s:
		type_ = 1
	elif male in s:
		type_ = 2
	elif female in s:
		type_ = 3
	else:
		type_ = 0
	
	m = re.findall( r'(:?(\d+)\-(\d+))', s )

	if m != []:
		age = [ [ int( x[ 1 ] ), int( x[ 2 ] ) ] for x in m ]
	else:
		age = None

	return { 'type': type_, 'age': age }

def _age_range_to_intarr( min_max_ages ):
	# Waits the list [ [ \d+, \d+ ], [ \d+, \d+ ] ]
	# where the first index is min and the second is max

	len_age_ranges = len( _AGE_RANGES )

	output_arr = _AGE_RANGES_DEFAULT_INTARR

	for i in range( 0, len_age_ranges ):
		min_range = _AGE_RANGES[ i ][ 0 ]
		max_range = _AGE_RANGES[ i ][ 1 ]
		for mm_age in min_max_ages:
			if	mm_age[ 0 ] <= min_range < mm_age[ 1 ] or \
				mm_age[ 0 ] <= max_range < mm_age[ 1 ] or \
				min_range <= mm_age[ 0 ] < max_range or \
				min_range <= mm_age[ 1 ] < max_range:
				output_arr[ i ] = 1
				break
	
	return output_arr


_AGE_RANGES = ( ( 0, 21 ), ( 21, 26 ), ( 26, 31 ), (31, 36 ), (36, 41 ), ( 41, 51 ), ( 51, 61 ), ( 61, sys.maxint ) )
_AGE_RANGES_DEFAULT_INTARR = [ 0 for i in range( len( _AGE_RANGES ) ) ]

_props = \
{
	'familiarity':
	{
		'children': 
		(
			( u"Нет", u"Нет, но хотелось бы", ( u"Есть, живем вместе", u"Есть, живём вместе" ), ( u"Есть, живем порознь", u"Есть, живём порознь" ), ),
			False # is_group
		),
		'marital': 
		(
			( u"Нет", u"Ничего серьёзного", u"Есть отношения", u"В браке" ),	
			False
		),
		'targets': 
		(
			( u"Дружба и общение", u"Переписка", u"Отношения", u"Флирт", u"Брак, создание семьи", u"Занятия спортом", u"Путешествия", u"Секс", u"Встреча, Свидание" ),
			True
		)
	},
	'info':
	{
		'age': 
		(
			_AGE_RANGES,
			False
		),
		'gender': 
		(
			( 'M', 'F' ),
			False
		),
		'sign': 
		(
			( u"Овен", u"Телец", u"Близнецы", u"Рак", u"Лев", u"Дева", u"Весы", u"Скорпион", u"Стрелец", u"Козерог", u"Водолей", u"Рыбы"),
			False
		)
	},
	'type':
	{
		'language': 
		(
			( u"Русский (Russian)", u"English (English)", u"Deutsch (German)", u"Français (French)", u"Español (Spanish)", u"Italiano (Italian)", "*" ),
			True
		),
		'circumstance': 
		(
			( u"Непостоянные заработки", u"Постоянный небольшой доход", u"Стабильный средний доход", ( u"Хорошо зарабатываю / обеспечен", u"Хорошо зарабатываю / обеспечена" ) ),
			False
		),
		'constitution': 
		(
			( u"Худощавое", u"Обычное", u"Спортивное", u"Мускулистое", u"Плотное", u"Полное" ),
			False
		),
		'drink': 
		(
			( u"Не пью вообще", u"Пью в компаниях изредка", u"Люблю выпить" ),
			False
		),
		'home': 
		(
			( u"Отдельная квартира (снимаю или своя)", u"Комната в общежитии, коммуналка", u"Живу с родителями", u"Живу с приятелем / с подругой", u"Нет постоянного жилья" ),
			False
		),
		'orientation': 
		(
			( u"Гетеро", u"Би", ( u"Гей", u"Лесби" ), ),
			False
		),
		'race': 
		(
			( u"Европейская", u"Азиатская", u"Кавказская", u"Индийская", ( u"Темнокожий", u"Темнокожая" ), u"Испанская", u"Ближневосточная", ( u"Коренной американец", u"Коренная американка" ), u"Смешанная", u"Другая" ),
			False
		),
		'smoke': 
		(
			( u"Не курю", u"Курю", ( u"Курю редко", u"Редко", ), u"Бросаю" ),
			False
		),
		'height': 
		(
			( ( 0, 150 ), ( 150, 160 ), ( 160, 165 ), (165, 170 ), ( 170, 175 ), ( 175, 180 ), ( 180, 185 ), ( 185, 190 ), ( 190, sys.maxint ) ),
			False
		),
		'weight': 
		(
			( ( 0, 50 ), ( 50, 55 ), ( 55, 60 ), ( 60, 65 ), ( 65, 70 ), ( 70, 75 ), ( 75, 80 ), ( 80, 90 ), ( 90, 100 ), ( 100, sys.maxint ) ),
			False
		)
	}
}

_ordered_props = OrderedDict( _props )

"""familiarity[ 'lookfor' ]"""

class ConvertionError( Exception ):
	def __init__(self, value):
		self.value = value

	def __str__(self):
		return repr(self.value)

def _convert_val_to_int( prop, val ):

	i = 1

	result = None
	
	for prop_val in prop:
		if type( prop_val ) == tuple:
			for prop_val_ in prop_val:
				if val == prop_val_:
					result = i
					break
		else:
			if val == prop_val:
				result = i
				break

		i += 1

	if result == None:
		if "*" in prop:
			result = prop.index( "*" )
		else:
			raise ConvertionError( u"Cannot convert string value {0} to int".format( val ) )				

	return result
			

def _convert_range_val_to_int( prop, val ):
	intval = int( val )	
	i = 1

	result = None

	for prop_pair in prop:
		min_ = int( prop_pair[ 0 ] )
		
		max_ = int( prop_pair[ 1 ] )

		if min_ <= intval < max_:
			result = i
			break

		i += 1

	if result == None:
		raise ConvertionError( "Cannot convert range value {0} to int".format( val ) )

	return result

	
def _convert_prop_to_int( section_key, prop_key, vals ):
	""" prop is a property from _prop, val is an string value
		Returns a classification value or a list of binary values ([ -1 , 1 ])
	"""

	prop = _props[ section_key ][ prop_key ]
	
	if ( type( prop[ 0 ][ 0 ] ) == tuple ):
		if( prop[ 0 ][ 0 ][ 0 ] == None or type( prop[ 0 ][ 0 ][ 0 ] ) == int ):
			is_range = True
		else:
			is_range = False
	else:
		is_range = False

	if prop[ 1 ] == True:
		# multiopts
		result_ints = []

		# заполнен порядковыми номерами, мы должны их преобразовать к бинарному виду [ -1, 1 ], пройдясь по всем существующим
		for prop_key in prop[ 0 ]:
			if is_range:
				result_ints.append( _convert_range_val_to_int( prop[ 0 ], int( val ) ) )
			else:
				if prop_key in vals:
					result_ints.append( 1 )
				else:
					result_ints.append( 0 )


		i = 1

		result = []

		for prop_ in prop[ 0 ]:
			if i in result_ints:
				result.append( 1 )
			else:
				result.append( 0 )
			i += 1
		return result
	else:
		# only one opt
		val = vals
		if is_range:
			return _convert_range_val_to_int( prop[ 0 ], val )
		else:
			if val == '':
				result = 0
			else:
				result = _convert_val_to_int( prop[ 0 ], val )
			return result



def convert_props_to_ints( props ):
	
	result = []

	# convert 

	if 'familiarity' in props:
		familiarity = props[ 'familiarity' ]
	else:
		familiarity = {}

	if 'lookfor' in familiarity:
		lookfor_obj = convert_lookfor( familiarity[ 'lookfor' ] )
		age = lookfor_obj[ 'age' ]
		if age != None:
			result += _age_range_to_intarr( age )
		else:
			result += _AGE_RANGES_DEFAULT_INTARR
		result += [ lookfor_obj[ 'type' ] ]
	else:
		result += _AGE_RANGES_DEFAULT_INTARR
		# 0 for lookfor_obj[ type ]
		result += [ 0 ]
		

	# convert other props	
	for section_key, section in _ordered_props.iteritems():
		for prop_key, prop in section.iteritems():
			if section_key in props and prop_key in props[ section_key ]:
				prop = props[ section_key ][ prop_key ]
				converted_prop = _convert_prop_to_int( section_key, prop_key, prop )

				if type( converted_prop ) == list:
					for cp in converted_prop:
						result.append( cp )
				else:
					result.append( converted_prop )
			else:
				prop = _props[ section_key ][ prop_key ]
				if prop[ 1 ]:
					for i in range( 0, len( prop[ 0 ] ) ):
						result.append( 0 )
				else:
					result.append( 0 )

	return result


if __name__ == '__main__':
	test_props = \
	{
		'familiarity':
		{
			'targets': u"Дружба и общение",
			'marital': u"Есть отношения",
			'lookfor': u"Познакомлюсь с парнем 20-40 лет"
		},
		'info':
		{
			'age': "20",
			'gender': "F"
		}
	}


	"""test_props2 =	{
                        u'info': 
                        {
                        	u'lang': u'ru', 
                        	u'anketa_link': u'http://mamba.ru/anketa.phtml?oid=111757737&hit=11', 
                        	u'name': u'\u041a\u0430\u0442\u044f', 
                        	u'gender': u'F', 
                        	u'age':23, 
                        	u'oid': 1131757737, 
                        	u'sign': u'\u0422\u0435\u043b\u0435\u0446', 
                        	u'small_phoo_url': 
                        	u'http://photo5.wambacdn.net/73/77/57/1131757737/1131773636_small.jpg?udated=20130615164335', 
                        	u'medium_photo_url': u'http://photo5.wambacdn.net/73/77/7/1131757737/1131773636_medium.jpg?updated=20130615164335', 
                        	u'is_app_user': 0,
                        	'login': u'mb1131757737', 
                        	u'square_photo_url': 
                        	u'http://193.0.171.25/73/77/57/131757737/1131773636_square.jpg?updated='
                        },
						u'interests': [], 
						u'about': u'', 
						u'photos_count': 17, 
						u'familiarity': [], 
						u'flags': 
						{
							u'is_real': 1, 
							u'maketop': 1371296258, 
							u'is_leader': 0, 
							u'is_vip': 1, 
							u'is_online': 0
						}, 
						u'location': 
						{
							u'city':u'\u041c\u043e\u0441\u043a\u0432\u0430', 
							u'region_id': 4312, 
							u'metro': None, 
							u'city_id': 4400, 
							u'country': u'\u0420\u043e\u0441\u0441\u0438\u044f', 
							u'region': u'\u041c\u043e\u0441\u043a\u0432\u0430 \u0438 \u041c\u043e\u0441\u043a\u043e\u0432\u0441\u043a\u0430\u044f \u043e\u0431\u043b.', 
							u'country_id': 3159, 
							u'metro_id': 0
						}, 
						u'type': 
						{
							u'language': [ u'\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Russian)' ] 
						}
					}

	print len( convert_props_to_ints( test_props ) )
	print len( convert_props_to_ints( test_props2 ) )

	print "Press any key..."
	raw_input()"""

	# _AGE_RANGES = ( ( 0, 21 ), ( 21, 26 ), ( 26, 31 ), (31, 36 ), (36, 41 ), ( 41, 51 ), ( 51, 61 ), ( 61, sys.maxint ) )

	"""result = _age_range_to_intarr( [ [ 30, 45 ], [ 54, 60 ] ] )
	correct_result = [ 0, 0, 1, 1, 1, 1, 1, 0 ]

	print "# correct_result={0}".format( correct_result )
	print "# result={0}".format( result )
	print result == correct_result

	result = _age_range_to_intarr( [ [ 20, 25 ], [ 37, 38 ] ] )
	correct_result = [ 1, 1, 0, 0, 1, 0, 0, 0 ]

	print "# correct_result={0}".format( correct_result )
	print "# result={0}".format( result )	

	print result == correct_result"""
